
package com.youdo.ad.loader {

	import com.youdo.ad.core.XAdManager;
	import com.youdo.utils.URLUtils;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.Security;
	import flash.system.SecurityDomain;
	import flash.external.ExternalInterface;

	import org.osflash.signals.Signal;
	import org.osflash.signals.natives.NativeSignal;

	/**
	 * 
	 */
	public class XAdManagerLoader extends Sprite {

		public static const DEFAULT_AD_MANAGER_URL : String = "http://www.google.com/adsense/AdManager.swf";
		//
		/**
		 * @see signal4IOError
		 * @see signal4SecurityError
		 */
		public var signal4Completed : Signal;
		/**
		 * @see signal4Completed
		 * @see signal4SecurityError
		 */
		public var signal4IOError : Signal;
		/**
		 * @see signal4Completed
		 * @see signal4IOError
		 */
		public var signal4SecurityError : Signal;
		//
		//
		//
		private var _adManagerComponent : MovieClip;
		//
		//
		// Security.LOCAL_WITH_FILE,Security.LOCAL_WITH_NETWORK, Security.LOCAL_TRUSTED
		private var _isLocalLoadMode : Boolean;
		//
		//
		private var _container : DisplayObjectContainer;
		private var _loader : Loader;


		/**
		 * 
		 */
		public function XAdManagerLoader() {
			this._isLocalLoadMode = false;
			//
			this.signal4Completed = new Signal();
			this.signal4IOError = new Signal();
			this.signal4SecurityError = new Signal();
		}

		/**
		 * 
		 */
		public function loadAdManager(url:String=null, container : DisplayObjectContainer=null, cacheBuster : Number=1) : void {
			this._container = container;
			//
			this._loader = new Loader();
			(new NativeSignal( this._loader.contentLoaderInfo, Event.COMPLETE, Event )).addOnce( this.handleLoadCompleted );
			(new NativeSignal( this._loader.contentLoaderInfo, IOErrorEvent.IO_ERROR, IOErrorEvent )).add( this.handleIOError );
			(new NativeSignal( this._loader.contentLoaderInfo, SecurityErrorEvent.SECURITY_ERROR, SecurityErrorEvent )).add( this.handleSecurityError );
			//
			var url : String = url==null?DEFAULT_AD_MANAGER_URL:url;
			if (URLUtils.isHTTP( url )) {
				Security.allowDomain( URLUtils.getDomain( url ) );
			}
			if (Security.sandboxType == Security.REMOTE) {
				if (!isNaN( cacheBuster )) {
					url = url + ("&cb=" + cacheBuster);
				}
			} else {
				this._isLocalLoadMode = true;
			}
			//
			var ctx : LoaderContext = new LoaderContext();
			ctx.applicationDomain = new ApplicationDomain();
			switch(Security.sandboxType) {
				case Security.LOCAL_TRUSTED:
				case Security.LOCAL_WITH_FILE:
				case Security.LOCAL_WITH_NETWORK:
					this._loader.load( new URLRequest( url ), ctx );
					break;
				case Security.REMOTE:
					ctx.securityDomain = SecurityDomain.currentDomain;
					this._loader.load( new URLRequest( url ), ctx );
				default:
					break;
			}
			//
			if (container is DisplayObjectContainer) {
				container.addChild( this._loader );
			}
		}

		/**
		 * 
		 */
		public function newAdManager() : com.youdo.ad.core.XAdManager {
			var am:XAdManager = null;
			if (this._adManagerComponent) {
				am = new com.youdo.ad.core.XAdManager( this._adManagerComponent.getNewInstance(1) );
			}
			return am;
		}

		private function handleLoadCompleted(event : Event) : void {
			this._adManagerComponent = MovieClip( this._loader.content );
			if (this._container && this._container.stage) {
				this._adManagerComponent.initialize( {stageURL:this._container.stage.loaderInfo.url} );
			}
			if (this._isLocalLoadMode) {
				this._adManagerComponent.initialize( {} );
			}
			this.signal4Completed.dispatch();
		}

		private function handleIOError(event : IOErrorEvent) : void {
			this.signal4IOError.dispatch();
		}

		private function handleSecurityError(event : SecurityErrorEvent) : void {
			this.signal4SecurityError.dispatch();
		}
	}
}